package com.lihuinch.test.feishu.eventsubscribe.handler.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.core.type.TypeReference;
import com.lihuinch.test.feishu.eventsubscribe.constant.TestConstants;
import com.lihuinch.test.feishu.eventsubscribe.feishu.FeishuNotifyDataDecrypter;
import com.lihuinch.test.feishu.eventsubscribe.handler.FeishuEventHandler;
import com.lihuinch.test.feishu.eventsubscribe.handler.response.FeishuEventResponse;
import com.lihuinch.test.feishu.eventsubscribe.util.SpringContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 。事件处理 包含 加密和解密
 *
 * @author lihu
 * @date 2021-8-27 16:51
 * @since
 */
@Primary
@Service(FeishuEventHandler.FEI_SHU_EVENT_HANDLER + "")
public class FeishuEventHandlerImpl implements FeishuEventHandler<FeishuEventResponse> {

    private Logger logger = LoggerFactory.getLogger(getClass());
//
//
//    private FeishuEventContactUserUpdatedV3Handler feishuEventContactUserUpdatedV3Handler;
//
//    @Autowired
//    public void setFeishuEventContactUserUpdatedV3Handler(FeishuEventContactUserUpdatedV3Handler feishuEventContactUserUpdatedV3Handler) {
//        this.feishuEventContactUserUpdatedV3Handler = feishuEventContactUserUpdatedV3Handler;
//    }

    @Override
    public FeishuEventResponse handleEvent(JSONObject param) {
        if (param == null) {
            throw new RuntimeException("FeishuEventHandlerImpl param 为空");
        }
        /*JSONObject event = param.getJSONObject("event");
        JSONObject object = event.getJSONObject("object");
        object.put("name","2222");

        System.out.println(object);*/

        // 是不是要解密
        param = ifNeedDecode(param);

        logger.info("handleEvent param \n{}", JSON.toJSONString(param, SerializerFeature.PrettyFormat));

        // 判定是什么请求
        String whatEvent = null;

        // 是不是验证接口
        if (param.containsKey(TestConstants.FeiShuParam.VERIFY_URL_CHALLENGE)) {
            whatEvent = TestConstants.FeishuEvent.VERIFY_URL;
        } else {
            // 2.0版本
            // 目前响应事件的数据格式有2个版本，现在新接入的事件都是采用2.0版本的格式。
            // 事件返回包含schema字段，则是2.0版本；
            if (Objects.equals(param.getString(TestConstants.FeiShuParam.EVENT_SCHEMA), TestConstants.FeiShuParam.EVENT_SCHEMA_V2)) {
                JSONObject header = param.getJSONObject(TestConstants.FeiShuParam.EVENT_HEADER);
                if (header == null) {
                    throw new RuntimeException("header == null");
                }

                logger.info("header \n{}", JSON.toJSONString(header, SerializerFeature.PrettyFormat));

                whatEvent = header.getString(TestConstants.FeiShuParam.Header.EVENT_TYPE);
            } else {
                // v1
            }
        }

        if (whatEvent != null) {

            FeishuEventHandler handler = SpringContextUtil.getBean(FeishuEventHandler.getBeanId(whatEvent), FeishuEventHandler.class);
            if (handler == null) {
                throw new RuntimeException("handler bean查找失败" + whatEvent);
            }

            return handler.handleEvent(param);
        }

        throw new RuntimeException("不支持的事件类型!");
    }

    private JSONObject ifNeedDecode(JSONObject param) {

        // 判断是不是加密请求
        if (param.containsKey(TestConstants.FeiShuParam.VERIFY_URL_ENCRYPT)) {

            String encrypt = param.getString(TestConstants.FeiShuParam.VERIFY_URL_ENCRYPT);
            // 加密的属于
            String encryptKey = TestConstants.encryptKey;
            if (encryptKey == null) {
                throw new RuntimeException("加密的属于, 但是本地没encryptKey");
            }

            // 设置了加密参数encryptKey
            // 未设置加密参数encryptKey不需要解密
            FeishuNotifyDataDecrypter decrypter = new FeishuNotifyDataDecrypter(encryptKey);
            try {
                String json = decrypter.decrypt(encrypt);
                return JSONObject.parseObject(json);
            } catch (Exception e) {
                throw new RuntimeException("解密challenge失败");
            }
        } else {
            return param;
        }
    }
}
